
import { guid } from "../../core/utils";
import { tween } from "./tween";
/**
 * 动画数据采样类。由三部分构成
 * 1. times 动画的时间序列
 * 2. values 对应times，再每一个时间点的值。
 * 3. interpolation 插值方式，缺省："LINEAR"，同时，可以通过easing指定缓动方式，缺省"none"不缓动。缓动{@link tween}
 * @class
 * @memberof w.animation
 */
class Sampler{
    /**
     * 
     * @param {Array} times 动画的时间序列。单位：秒(s)。
     * @param {Array} values 动画的值序列。
     * @param {String} interpolation 动画的插值方式。缺省："LINEAR"(线性插值)。{@link tween}
     * @param {String} easing 动画的缓动方式，缺省："none"，无缓动。可选值有：
     * 1. "none"
     * 2. "easeIn_Sine"|easeIn_Cubic|easeIn_Quint|easeIn_Circ|easeIn_Elastic|easeIn_Quad|easeIn_Quart|easeIn_Expo|easeIn_Back|easeIn_Bounce
     * 3. "easeOut_Sine"|easeOut_Cubic|easeOut_Quint|easeOut_Circ|easeOut_Elastic|easeOut_Quad|easeOut_Quart|easeOut_Expo|easeOut_Back|easeOut_Bounce
     * 4. "easeInOut_Sine"|easeInOut_Cubic|easeInOut_Quint|easeInOut_Circ|easeInOut_Elastic|easeInOut_Quad|easeInOut_Quart|easeInOut_Expo|easeInOut_Back|easeInOut_Bounce
     * @example
     *  let aniSystem=new w.animation.AnimationSystem();
     *  let sampler=new w.animation.Sampler([0,40], [[0,0],[-100,0]],"LINEAR", "none");
     *  let channel=new w.animation.Channel(m,"map_uvOffset");
     *  channel.add(sampler);
     *  let animation=new w.animation.Animation({id:"uvOffset",running:true});
     *  animation.add(channel);
     *  aniSystem.add(animation);
     */
    constructor(times,values,interpolation="LINEAR",easing="none"){
        this.id=guid();
        this.times=times;
        this.values=values; 
        this.easing=easing;
        this.interpolation=tween[interpolation];
    }
    timeLine(){
        return [this.times[0],this.times[this.times.length-1]];
    }

    /**
     * 生成往返动画的动画闭环。
     * @method
     * @returns {w.animation.Sampler}
     */
    invert(){
        let values=[...this.values];
        let times=[...this.times];
        const len=this.times.length;
        let total=this.times[len-1];
        for(let i=0;i<len-1;i++){
            total=total+times[len-1-i]-times[len-2-i];
            times.push(total);
            values.push(this.values[len-2-i]);
        }
        this.times=times;
        this.values=values;
        return this;
    }
    /**
     * 从给定的时间参数中找出关键帧。
     * @method
     * @param {Number} time 流逝的时间，单位：s。
     * @returns {*} 返回该关键帧的属性值。
     */
    findKeyFrame(time){
        let _i=0;
        let len=this.times.length
        if(time<this.times[0]){
            time=this.times[0];//时间小于input第一个值，
        }else if(time>=this.times[len-1]){
            time=this.times[len-1];//时间大于input最后一个值，
        }
        for(let i=0;i<len-1;i++){
            if(time>this.times[i] && time<=this.times[i+1]){// 找出帧时间在哪个区间的索引
                _i=i;
                break;
            }
        }
        let out;
        const _b=this.times[_i]//前一个值
        const _e=this.times[_i+1];//后一个值
        let _f=[];//前一个value
        let _t=[];//后一个value
        let gc=this.times.length;
        let vc=this.values.length;
        if(vc>gc){//展开的方式提供，先进行分组
            let c=vc/gc;
            _f=this.values.slice(_i*c,(_i+1)*c);
            _t=this.values.slice((_i+1)*c,(_i+2)*c);
        }else{
            _f=this.values[_i];
            _t=this.values[_i+1];
        }
        out=this.interpolation(time-_b,_f,_t,Math.abs(_e-_b),this.easing);
        return out;
    }
}
export {Sampler}